/**
 * 配置
 * */
package org.zmhhxl.api.auth.configure;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.security.jackson2.CoreJackson2Module;

/**
 * Redis的key序列化配置类,被RedisSecurityContextRepositorysy使用
 *
 * @author vains
 */
//@Configuration
@RequiredArgsConstructor
//@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)
public class RedisConfig {
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        // 这里可以根据实际情况创建LettuceConnectionFactory或JedisConnectionFactory的实例
        return new LettuceConnectionFactory();
    }

    private final Jackson2ObjectMapperBuilder builder;

//    /**
//     * 统一创建RedisTemplate的Bean方法，用于提高代码的可维护性和减少重复代码。
//     *
//     * @param connectionFactory Redis连接工厂
//     * @param <K>              键的类型
//     * @param <V>              值的类型
//     * @return RedisTemplate
//     */
//    @SuppressWarnings("unchecked")
//    @Bean
//    public <K, V> RedisTemplate<K, V> redisTemplate(RedisConnectionFactory connectionFactory) {
//        RedisTemplate<K, V> redisTemplate = new RedisTemplate<>();
//
//        // 字符串序列化器
//        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//        redisTemplate.setKeySerializer(stringRedisSerializer);
//        redisTemplate.setStringSerializer(stringRedisSerializer);
//        redisTemplate.setHashKeySerializer(stringRedisSerializer);
//
//        // 创建ObjectMapper并添加默认配置
//        ObjectMapper objectMapper = configureObjectMapper(builder.createXmlMapper(false).build());
//
//        // 序列化器
//        Jackson2JsonRedisSerializer<V> valueSerializer = new Jackson2JsonRedisSerializer<>(objectMapper, V.class);
//        redisTemplate.setValueSerializer(valueSerializer);
//        redisTemplate.setHashValueSerializer(valueSerializer);
//
//        // 设置连接工厂
//        redisTemplate.setConnectionFactory(connectionFactory);
//
//        return redisTemplate;
//    }
//
//    /**
//     * 配置ObjectMapper。
//     *
//     * @param objectMapper ObjectMapper实例
//     * @return 配置后的ObjectMapper实例
//     */
//    private ObjectMapper configureObjectMapper(ObjectMapper objectMapper) {
//        // 设置所有字段可序列化
//        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//
//        // 配置类型信息，以处理多态性
//        objectMapper.activateDefaultTyping(
//              objectMapper.getPolymorphicTypeValidator(),
//              ObjectMapper.DefaultTyping.NON_FINAL,
//              JsonTypeInfo.As.PROPERTY);
//
//        // 注册Security提供的Jackson Mixin
//        objectMapper.registerModule(new CoreJackson2Module());
//
//        return objectMapper;
//    }



    /**
     * 默认情况下使用
     *
     * @param connectionFactory redis链接工厂
     * @return RedisTemplate
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        // 字符串序列化器
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // 创建ObjectMapper并添加默认配置
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();

        // 序列化所有字段
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

        // 此项必须配置，否则如果序列化的对象里边还有对象，会报如下错误：
        //     java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to XXX
        objectMapper.activateDefaultTyping(
                objectMapper.getPolymorphicTypeValidator(),
                ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.PROPERTY);

        // 添加Security提供的Jackson Mixin
        objectMapper.registerModule(new CoreJackson2Module());

        // 存入redis时序列化值的序列化器
        Jackson2JsonRedisSerializer<Object> valueSerializer =
                new Jackson2JsonRedisSerializer<>(objectMapper, Object.class);

        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();


        // 默认的Key序列化器为：JdkSerializationRedisSerializer
        redisTemplate.setKeySerializer(stringRedisSerializer);
        // 设置值序列化
        redisTemplate.setValueSerializer(valueSerializer);
        //redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        // 设置字符串序列化器
        redisTemplate.setStringSerializer(stringRedisSerializer);
        // 设置hash结构的key的序列化器
        redisTemplate.setHashKeySerializer(stringRedisSerializer);  //
        // 设置hash格式数据值的序列化器
        redisTemplate.setHashValueSerializer(valueSerializer);
        //redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        // 设置连接工厂
        redisTemplate.setConnectionFactory(connectionFactory);

        return redisTemplate;
    }


    /**
     * zmhhxl 2024-2-2
     * 操作hash的情况下使用
     *
     * @param connectionFactory redis链接工厂
     * @return RedisTemplate
     */
//    @Bean
//    public RedisTemplate<Object, Object> redisHashTemplate(RedisConnectionFactory connectionFactory) {
//
//        return redisTemplate(connectionFactory);
//    }


}
